package gui.newgui.archerdbeditor;

import gui.newgui.IController;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Observable;
import java.util.Observer;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;

import table.models.ArcherDBTableModel;
import table.models.ParticipantsTableModel;
import tournamentData.TournamentData;
import core.Date;
import core.Person;
import db.newversion.ArchersDB;
import db.newversion.DbEntry;

public class NewArcherDBEditorController implements IController, Observer {
	private final NewArcherDBEditor window;

	public NewArcherDBEditorController(NewArcherDBEditor newArcherDBEditor) {
		this.window = newArcherDBEditor;
		ArchersDB.getInstance().addObserver(this);
		TournamentData.getInstance().addObserver(this);
	}

	@Override
	public void updateTable() {
		HashMap < Integer, Person > all = ArchersDB.getInstance().getAll();
		ParticipantsTableModel nonParticipantsTableModel = (ParticipantsTableModel) this.window.getTable().getModel();
		nonParticipantsTableModel.removeData();
		if (all.size() > 0) {
			Iterator < Entry < Integer, Person >> iterator = all.entrySet().iterator();
			while (iterator.hasNext()) {
				Entry < Integer, Person > toAdd = iterator.next();
				nonParticipantsTableModel.addRow(new Object [] { toAdd.getKey(), toAdd.getValue().getName(), toAdd.getValue().getSurName(), toAdd.getValue().getNation(),
						toAdd.getValue().getCountry(), toAdd.getValue().getBowCathegory(), toAdd.getValue().getAgeClass(), toAdd.getValue().getClub(), toAdd.getValue().getGender(),
						toAdd.getValue().isLicense(), toAdd.getValue().isCountryRating(), toAdd.getValue().getBirthdate() });
			}

			nonParticipantsTableModel.fireTableDataChanged();
		}
	}

	public void setDropDownMenus() {
		String [] nations = ArchersDB.getInstance().getAll(DbEntry.NATION);
		java.util.Arrays.sort(nations);
		this.window.getNationDropDown().setModel(this.comboBoxModelFactory(nations));

		String [] countries = ArchersDB.getInstance().getAll(DbEntry.COUNTRY);
		java.util.Arrays.sort(countries);
		this.window.getCountryDropDown().setModel(this.comboBoxModelFactory(countries));

		String [] bowCathegories = ArchersDB.getInstance().getAll(DbEntry.BOWCATHEGORY);
		java.util.Arrays.sort(bowCathegories);
		this.window.getBowCathegoryDropDown().setModel(this.comboBoxModelFactory(bowCathegories));

		String [] ageClasses = ArchersDB.getInstance().getAll(DbEntry.AGECLASS);
		java.util.Arrays.sort(ageClasses);
		this.window.getAgeClassDropDown().setModel(this.comboBoxModelFactory(ageClasses));

		String [] clubs = ArchersDB.getInstance().getAll(DbEntry.CLUB);
		java.util.Arrays.sort(clubs);
		this.window.getClubDropDown().setModel(this.comboBoxModelFactory(clubs));

		String [] genders = ArchersDB.getInstance().getAll(DbEntry.GENDER);
		java.util.Arrays.sort(genders);
		this.window.getGenderDropDown().setModel(this.comboBoxModelFactory(genders));
	}

	@Override
	public void update(Observable arg0, Object arg1) {
		this.updateTable();
		this.setDropDownMenus();
	}

	public void filloutForm() {

		int row = this.window.getTable().convertRowIndexToModel(this.window.getTable().getSelectedRow());

		String name = this.window.getTable().getModel().getValueAt(row, 1).toString();
		this.window.getNameTextField().setText(name);
		String surName = this.window.getTable().getModel().getValueAt(row, 2).toString();
		this.window.getSurNameTextField().setText(surName);
		String nation = this.window.getTable().getModel().getValueAt(row, 3).toString();
		this.window.getNationDropDown().setSelectedItem(nation);
		String country = this.window.getTable().getModel().getValueAt(row, 4).toString();
		this.window.getCountryDropDown().setSelectedItem(country);
		String bowCathegory = this.window.getTable().getModel().getValueAt(row, 5).toString();
		this.window.getBowCathegoryDropDown().setSelectedItem(bowCathegory);
		String ageClass = this.window.getTable().getModel().getValueAt(row, 6).toString();
		this.window.getAgeClassDropDown().setSelectedItem(ageClass);
		String club = this.window.getTable().getModel().getValueAt(row, 7).toString();
		this.window.getClubDropDown().setSelectedItem(club);
		String gender = this.window.getTable().getModel().getValueAt(row, 8).toString();
		this.window.getGenderDropDown().setSelectedItem(gender);
		Boolean isLicense = new Boolean(this.window.getTable().getModel().getValueAt(row, 9).toString());
		this.window.getLicenseCheckBox().setSelected(isLicense);
		Boolean isCountryRating = new Boolean(this.window.getTable().getModel().getValueAt(row, 10).toString());
		this.window.getCountryRatingCheckBox().setSelected(isCountryRating);
		String birthDate = this.window.getTable().getModel().getValueAt(row, 11).toString();
		this.window.getBirthDateTextField().setText(birthDate);
		int playerID = Integer.parseInt(this.window.getTable().getModel().getValueAt(row, 0).toString());
		this.window.getTournamentParticipationCheckBox().setSelected(TournamentData.getInstance().isParticipating(playerID));
	}

	private ComboBoxModel comboBoxModelFactory(Object [] content) {
		return new DefaultComboBoxModel(content);
	}

	/**
	 * @param update
	 *            true if an existing entry should be updated, false if a new
	 *            entry should be generated
	 */
	public void saveEntry(boolean update) {
		boolean error = false;

		String name = this.window.getNameTextField().getText();
		String surName = this.window.getSurNameTextField().getText();
		String nation = this.window.getNationDropDown().getSelectedItem().toString();
		String country = this.window.getCountryDropDown().getSelectedItem().toString();
		String bowCathegory = this.window.getBowCathegoryDropDown().getSelectedItem().toString();
		String ageClass = this.window.getAgeClassDropDown().getSelectedItem().toString();
		String club = this.window.getClubDropDown().getSelectedItem().toString();
		String gender = this.window.getGenderDropDown().getSelectedItem().toString();
		boolean license = this.window.getLicenseCheckBox().isSelected();
		boolean countryRating = this.window.getCountryRatingCheckBox().isSelected();
		boolean isParticipatingAtTournament = this.window.getTournamentParticipationCheckBox().isSelected();
		String birthDate = new Date(this.window.getBirthDateTextField().getText()).toString();

		if (name.isEmpty()) {
			error = true;
		}
		if (surName.isEmpty()) {
			error = true;
		}
		if (nation.isEmpty()) {
			error = true;
		}
		if (country.isEmpty()) {
			error = true;
		}
		if (bowCathegory.isEmpty()) {
			error = true;
		}
		if (ageClass.isEmpty()) {
			error = true;
		}
		if (club.isEmpty()) {
			error = true;
		}
		if (gender.isEmpty()) {
			error = true;
		}

		if (!error) {
			Person person = new Person(name, surName, nation, country, bowCathegory, ageClass, club, gender, license, countryRating, birthDate);
			int modelRow;
			int row;

			try {
				modelRow = this.window.getTable().convertRowIndexToModel(this.window.getTable().getSelectedRow());
				row = this.window.getTable().getSelectedRow();

			} catch (IndexOutOfBoundsException e) {
				modelRow = 0;
				row = 0;
			}

			try {
				if (update) {
					if (modelRow > 0) {
						int playerID = Integer.parseInt(((ArcherDBTableModel) this.window.getTable().getModel()).getValueAt(modelRow, 0).toString());
						ArchersDB.getInstance().update(person, playerID);
						if (TournamentData.getInstance().isParticipating(playerID) != isParticipatingAtTournament) {
							TournamentData.getInstance().addRemovePlayer(playerID);
						}
					}
				} else {
					ArchersDB.getInstance().insert(person, null);
					TournamentData.getInstance().addRemovePlayer(ArchersDB.getInstance().getLatestInsertedID());
				}

			} catch (SQLException e) {

			}

			this.window.getTable().setRowSelectionInterval(row, row);
			this.filloutForm();
		}
	}

	public void setRowSelected(int playerID) {
		int rowIndexToFocus = 0;
		for (int i = 0; i < this.window.getTable().getRowCount(); i++) {
			if (this.window.getTable().getValueAt(i, 0).equals(playerID)) {
				rowIndexToFocus = i;
				break;
			}
		}
		this.window.getTable().setRowSelectionInterval(rowIndexToFocus, rowIndexToFocus);
	}

	public void makeDropDownsEditable(boolean isEditable) {
		this.window.getNationDropDown().setEditable(isEditable);
		this.window.getCountryDropDown().setEditable(isEditable);
		this.window.getBowCathegoryDropDown().setEditable(isEditable);
		this.window.getAgeClassDropDown().setEditable(isEditable);
		this.window.getClubDropDown().setEditable(isEditable);
		this.window.getGenderDropDown().setEditable(isEditable);
	}

	public void deleteEntry() {
		int modelRow = this.window.getTable().convertRowIndexToModel(this.window.getTable().getSelectedRow());
		int playerID = Integer.parseInt(((ArcherDBTableModel) this.window.getTable().getModel()).getValueAt(modelRow, 0).toString());
		try {
			ArchersDB.getInstance().delete(null, playerID);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
